----------- -- by Alundaio phantom_registry = {} ----------------------------- -- DynamicPhantom ----------------------------- class "DynamicPhantom" (object_binder) function DynamicPhantom:__init(obj) super(obj) phantom_registry[obj:section()] = phantom_registry[obj:section()] and phantom_registry[obj:section()] + 1 or 1 end function DynamicPhantom:net_destroy() phantom_registry[self.object:section()] = phantom_registry[self.object:section()] and phantom_registry[self.object:section()] - 1 or 0 object_binder.net_destroy(self) end function bind_phantom(obj) obj:bind_object(DynamicPhantom(obj)) end -------------------------------------------------------------------------------------- function spawn_dynamic_phantom(sec,pos,lvid) --utils_data.debug_write("spawn_dynamic_phantom") level.spawn_item(sec,pos,4294967295,65535,false) end function dynamic_phantom_count(sec) return phantom_registry[sec] or 0 end local function monster_on_update(npc,st) if not (npc and npc:alive()) then return end local tg = time_global() if (st.__phantom_check and tg < st.__phantom_check) then return end st.__phantom_check = tg + 5000 -- if (has_alife_info("bar_deactivate_radar_done")) then -- return -- end local phantom_section = ini_sys:r_string_ex(npc:section(),"spawn_phantom") if not (phantom_section) then return end --[[ if (db.actor) then if (db.actor:object("good_psy_helmet") ~= nil) then return end end --]] local can_spawn = sr_psy_antenna.psy_antenna and sr_psy_antenna.psy_antenna.global_state == 1 or ini_sys:r_bool_ex(npc:section(),"can_spawn_phantom",false) if not (can_spawn) then return end if not (xr_combat_ignore.fighting_with_actor_npcs[npc:id()]) then return end if (db.actor:position():distance_to_sqr(npc:position()) > 900) then return end local sec = ini_sys:r_string_ex(npc:section(),"spawn_phantom") if (sec and sec ~= "" and phantom_manager.dynamic_phantom_count(sec) > 2) then return end phantom_manager.spawn_dynamic_phantom(sec,npc:position()) end function on_game_start() if (level.spawn_item) then RegisterScriptCallback("monster_on_update",monster_on_update) end end --------------------------------------------------------------------------- -- LEGACY class "PhantomManager" function PhantomManager:__init() self.phantom_count = 0; end g_PhantomManager = PhantomManager(); function PhantomManager:add_phantom() self.phantom_count = self.phantom_count + 1; end function PhantomManager:remove_phantom() self.phantom_count = self.phantom_count - 1; end function PhantomManager:spawn_phantom(pos) level.spawn_phantom(pos) end class "Phantom" (object_binder) function Phantom:__init(obj) super(obj) g_PhantomManager:add_phantom() end function bind(obj) obj:bind_object(Phantom(obj)) end function Phantom:reinit() object_binder.reinit(self) end function Phantom:net_spawn(se_abstract) if not object_binder.net_spawn(self, se_abstract) then return false end return true end function Phantom:update(delta) object_binder.update(self, delta) end function Phantom:net_destroy() g_PhantomManager:remove_phantom() object_binder.net_destroy(self) end function Phantom:reload(section) object_binder.reload(self, section) end function Phantom:net_save_relevant() return true end function Phantom:save(packet) set_save_marker(packet, "save", false, "Phantom") object_binder.save(self, packet) set_save_marker(packet, "save", true, "Phantom") end function Phantom:load(reader) set_save_marker(reader, "load", false, "Phantom") object_binder.load(self, reader) set_save_marker(reader, "load", true, "Phantom") end function spawn_phantom(pos) g_PhantomManager:spawn_phantom(pos) end function phantom_count() return g_PhantomManager.phantom_count end